package it.mauriziulu.android.ehttpexecutors.handler;

import it.mauriziulu.android.ehttpexecutors.ContentParser;
import it.mauriziulu.android.ehttpexecutors.request.EHttpRequest;
import it.mauriziulu.android.ehttpexecutors.response.EHttpResponseContainer;

import java.io.IOException;
import java.io.Serializable;

import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.ParseException;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpResponseException;
import org.apache.http.client.ResponseHandler;
import org.apache.http.util.EntityUtils;

public class DefaultResponseHandler implements EResponseHandler, ResponseHandler<Void> {
	private ContentParser mParser;
	private EHttpResponseContainer mResponseContainer;
	private ResponseHandlerChain mChain;
	private EHttpRequest mRequest;

	public DefaultResponseHandler(ContentParser parser) {
		mParser = parser;
	}

	@Override
	public void handle(EHttpRequest request, EHttpResponseContainer response, ResponseHandlerChain chain) throws ClientProtocolException, IOException {
		mResponseContainer = response;
		mChain = chain;
		mRequest = request;
		try {
			chain.getClient().execute(request, this, chain.getHttpContext());
		} catch (ClientProtocolException e) {
			throw new ClientProtocolException("Problem with protocol " + e.getMessage(), e);
		} catch (IOException e) {
			throw new IOException("Problem IO " + e.getMessage(), e);
		}
	}

	protected Serializable parse(String rawContent) {
		return mParser.parse(rawContent);
	}

	// protected HttpRequest buildGetRequest(String url, HttpRequestFactory
	// requestFactory) throws MethodNotSupportedException {
	// return requestFactory.newHttpRequest("GET", url);
	// }
	//
	// protected HttpHost buildTarget(String url) throws MalformedURLException {
	// URL _url = new URL(url);
	// return new HttpHost(_url.getHost());
	// }

	@Override
	public Void handleResponse(HttpResponse response) throws ClientProtocolException, IOException {
		mResponseContainer.setResponse(response);
		int statusCode = response.getStatusLine().getStatusCode();
		if (statusCode == HttpStatus.SC_OK) {
			mResponseContainer.addMessage("Response OK - parsing");
			try {
				mResponseContainer.setParsedResponse(parse(EntityUtils.toString(response.getEntity())));
			} catch (ParseException e) {
				throw new ClientProtocolException("Problem parsing document " + e.getMessage(), e);
			} catch (IOException e) {
				throw new IOException("Problem reading document " + e.getMessage(), e);
			}
			mChain.doHandle(mRequest, mResponseContainer);
		} else {
			mResponseContainer.addMessage("Bad server response: " + statusCode);
			throw new HttpResponseException(statusCode, "Bad server response, " + statusCode);
		}
		return null;
	}
}
